:D:\liu_thingsvue\electromagnetic-data-aggregation-web\src\views\scenario-simulation\home.vue
<!-- 剧情编辑工作台 - 重构版 -->
<template>
  <div class="scenario-workbench">
    <!-- 顶部工具栏 -->
    <div class="workbench-header">
      <div class="header-left">
        <h1 class="workbench-title">
          <el-icon class="title-icon"><Monitor /></el-icon>
          电磁场景编辑工作台
        </h1>
        <div class="project-info">
          <el-tag type="info" size="small">{{ currentProject.name }}</el-tag>
          <el-tag type="success" size="small" v-if="autoSaved">
            <el-icon><Check /></el-icon>
            已自动保存
          </el-tag>
        </div>
      </div>

      <div class="header-actions">
        <el-button-group class="action-group">
          <el-button size="small" @click="quickSave">
            <el-icon><DocumentAdd /></el-icon>
            快速保存
          </el-button>
          <el-button size="small" @click="previewScene">
            <el-icon><View /></el-icon>
            预览场景
          </el-button>
          <el-button size="small" type="primary" @click="runSimulation">
            <el-icon><VideoPlay /></el-icon>
            运行仿真
          </el-button>
        </el-button-group>
      </div>
    </div>

    <!-- 主工作区域 -->
    <div class="workbench-content">
      <!-- 左侧面板 -->
      <el-aside :width="leftPanelWidth" class="left-panel">
        <el-tabs v-model="leftActiveTab" stretch class="panel-tabs">
          <el-tab-pane label="装备部署" name="equipment">
            <EquipmentDeployer @dragStart="handleEquipmentDrag" />
          </el-tab-pane>
          <el-tab-pane label="航线规划" name="route">
            <RouteController
                ref="routeControllerRef"
                @startPlanning="handleStartPlanning"
                @finishPlanning="handleFinishPlanning"
                @cancelPlanning="handleCancelPlanning"
                @loadRoute="handleLoadRoute"
            />
          </el-tab-pane>
        </el-tabs>

        <!-- 面板调整器 -->
        <div
            class="panel-resizer left-resizer"
            @mousedown="startResize('left', $event)"
        ></div>
      </el-aside>

      <!-- 中央地图区域 -->
      <el-main class="map-area">
        <MapViewer
            ref="mapViewerRef"
            :routeData="currentRoute"
            :isPlanning="isPlanning"
            :planningMode="planningMode"
            @mapClick="handleMapClick"
            @equipmentDrop="handleEquipmentDrop"
        />
      </el-main>

      <!-- 右侧面板 -->
      <el-aside :width="rightPanelWidth" class="right-panel">
        <ScenarioPanel
            :selectedEquipment="selectedEquipment"
            :deployedEquipment="deployedEquipment"
            :routeCount="savedRoutes.length"
            @updateEquipment="handleUpdateEquipment"
            @removeEquipment="handleRemoveEquipment"
            @saveScene="handleSaveScene"
        />

        <!-- 面板调整器 -->
        <div
            class="panel-resizer right-resizer"
            @mousedown="startResize('right', $event)"
        ></div>
      </el-aside>
    </div>

    <!-- 底部状态栏 -->
    <div class="workbench-footer">
      <div class="status-left">
        <div class="status-item">
          <el-icon><Position /></el-icon>
          <span>装备数量: {{ deployedEquipment.length }}</span>
        </div>
        <div class="status-item">
          <el-icon><Guide /></el-icon>
          <span>路径数量: {{ savedRoutes.length }}</span>
        </div>
        <div class="status-item" v-if="isPlanning">
          <el-icon><EditPen /></el-icon>
          <span>{{ planningModeText }}规划中...</span>
        </div>
      </div>

      <div class="status-right">
        <div class="zoom-controls">
          <el-button-group size="small">
            <el-button @click="zoomIn">
              <el-icon><Plus /></el-icon>
            </el-button>
            <el-button @click="zoomOut">
              <el-icon><Minus /></el-icon>
            </el-button>
            <el-button @click="resetZoom">
              <el-icon><RefreshRight /></el-icon>
            </el-button>
          </el-button-group>
        </div>
        <div class="performance-indicator">
          <el-icon class="perf-icon" :class="{ active: performanceGood }"><Connection /></el-icon>
          <span class="perf-text">{{ performanceText }}</span>
        </div>
      </div>
    </div>

    <!-- 快捷操作浮动面板 -->
    <transition name="fade">
      <div v-if="showQuickPanel" class="quick-panel">
        <div class="quick-title">快捷操作</div>
        <div class="quick-actions">
          <el-button size="small" text @click="clearAll">
            <el-icon><Delete /></el-icon>
            清空场景
          </el-button>
          <el-button size="small" text @click="importScene">
            <el-icon><Upload /></el-icon>
            导入场景
          </el-button>
          <el-button size="small" text @click="exportScene">
            <el-icon><Download /></el-icon>
            导出场景
          </el-button>
        </div>
      </div>
    </transition>

    <!-- 全局快捷键提示 -->
    <div class="shortcut-tips" v-if="showShortcuts">
      <div class="tips-header">
        <span>快捷键</span>
        <el-button size="small" text @click="showShortcuts = false">
          <el-icon><Close /></el-icon>
        </el-button>
      </div>
      <div class="tips-content">
        <div class="tip-item">
          <kbd>Ctrl</kbd> + <kbd>S</kbd> 保存场景
        </div>
        <div class="tip-item">
          <kbd>Esc</kbd> 取消规划
        </div>
        <div class="tip-item">
          <kbd>Space</kbd> 快捷面板
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  Monitor,
  Check,
  DocumentAdd,
  View,
  VideoPlay,
  Position,
  Guide,
  EditPen,
  Plus,
  Minus,
  RefreshRight,
  Connection,
  Delete,
  Upload,
  Download,
  Close
} from '@element-plus/icons-vue'

// 导入子组件
import EquipmentDeployer from './components/scenario/EquipmentDeployer.vue'
import RouteController from './components/scenario/RouteController.vue'
import MapViewer from './components/scenario/MapViewer.vue'
import ScenarioPanel from './components/scenario/ScenarioPanel.vue'

// 组件引用
const routeControllerRef = ref(null)
const mapViewerRef = ref(null)

// 项目信息
const currentProject = reactive({
  name: '电磁对抗演练',
  created: new Date(),
  modified: new Date()
})

// UI状态
const leftActiveTab = ref('equipment')
const leftPanelWidth = ref('320px') /* 全屏模式下的合适宽度 */
const rightPanelWidth = ref('380px') /* 全屏模式下的合适宽度 */
const autoSaved = ref(false)
const showQuickPanel = ref(false)
const showShortcuts = ref(false)
const performanceGood = ref(true)

// 场景数据
const selectedEquipment = ref(null)
const deployedEquipment = ref([])
const savedRoutes = ref([])
const currentRoute = ref(null)

// 规划状态
const isPlanning = ref(false)
const planningMode = ref('ship')

// 调整面板大小相关
let isResizing = false
let resizeType = null
let startX = 0
let startWidth = 0

// 计算属性
const planningModeText = computed(() => {
  return planningMode.value === 'ship' ? '舰船' : '战机'
})

const performanceText = computed(() => {
  return performanceGood.value ? '良好' : '一般'
})

// 顶部工具栏操作
const quickSave = async () => {
  try {
    // 执行保存逻辑
    await new Promise(resolve => setTimeout(resolve, 500))
    autoSaved.value = true
    ElMessage.success('场景已快速保存')
    setTimeout(() => {
      autoSaved.value = false
    }, 2000)
  } catch (error) {
    ElMessage.error('保存失败')
  }
}

const previewScene = () => {
  ElMessage.info('预览功能开发中...')
}

const runSimulation = () => {
  if (deployedEquipment.value.length === 0) {
    ElMessage.warning('请先部署装备')
    return
  }
  ElMessage.success('仿真启动中...')
}

// 装备拖拽处理
const handleEquipmentDrag = (equipment) => {
  // 装备开始拖拽时的处理
}

// 航线规划处理
const handleStartPlanning = (mode) => {
  isPlanning.value = true
  planningMode.value = mode
  leftActiveTab.value = 'route'
}

const handleFinishPlanning = (routeData) => {
  savedRoutes.value.push(routeData)
  currentRoute.value = routeData
  isPlanning.value = false
}

const handleCancelPlanning = () => {
  isPlanning.value = false
  currentRoute.value = null
}

const handleLoadRoute = (route) => {
  currentRoute.value = route
}

// 地图交互处理
const handleMapClick = (coordinates) => {
  if (isPlanning.value && routeControllerRef.value) {
    routeControllerRef.value.addRoutePoint(coordinates)
  }
}

const handleEquipmentDrop = ({ equipment, coordinates }) => {
  const deployedItem = {
    ...equipment,
    deployedId: Date.now(),
    coordinates,
    status: 'active',
    deployTime: new Date()
  }

  deployedEquipment.value.push(deployedItem)
  ElMessage.success(`${equipment.name} 部署成功`)
}

// 装备管理
const handleUpdateEquipment = (equipment) => {
  const index = deployedEquipment.value.findIndex(item => item.deployedId === equipment.deployedId)
  if (index > -1) {
    deployedEquipment.value[index] = equipment
    ElMessage.success('装备信息已更新')
  }
}

const handleRemoveEquipment = (equipment) => {
  const index = deployedEquipment.value.findIndex(item => item.deployedId === equipment.deployedId)
  if (index > -1) {
    deployedEquipment.value.splice(index, 1)
    selectedEquipment.value = null
    ElMessage.success('装备已删除')
  }
}

// 场景保存
const handleSaveScene = (sceneData) => {
  currentProject.modified = new Date()
  ElMessage.success(`场景 "${sceneData.name}" 已保存`)
}

// 面板调整大小
const startResize = (type, event) => {
  isResizing = true
  resizeType = type
  startX = event.clientX
  startWidth = type === 'left' ?
      parseInt(leftPanelWidth.value) :
      parseInt(rightPanelWidth.value)

  document.addEventListener('mousemove', handleResize)
  document.addEventListener('mouseup', stopResize)
  document.body.style.cursor = 'col-resize'
}

const handleResize = (event) => {
  if (!isResizing) return

  const deltaX = event.clientX - startX

  if (resizeType === 'left') {
    const newWidth = Math.max(300, Math.min(450, startWidth + deltaX))
    leftPanelWidth.value = `${newWidth}px`
  } else if (resizeType === 'right') {
    const newWidth = Math.max(350, Math.min(500, startWidth - deltaX))
    rightPanelWidth.value = `${newWidth}px`
  }
}

const stopResize = () => {
  isResizing = false
  resizeType = null
  document.removeEventListener('mousemove', handleResize)
  document.removeEventListener('mouseup', stopResize)
  document.body.style.cursor = 'default'
}

// 缩放控制
const zoomIn = () => {
  if (mapViewerRef.value) {
    // 调用地图组件的缩放方法
    ElMessage.info('放大地图')
  }
}

const zoomOut = () => {
  if (mapViewerRef.value) {
    // 调用地图组件的缩放方法
    ElMessage.info('缩小地图')
  }
}

const resetZoom = () => {
  if (mapViewerRef.value) {
    // 调用地图组件的重置方法
    ElMessage.info('重置缩放')
  }
}

// 快捷操作
const clearAll = async () => {
  try {
    await ElMessageBox.confirm('确定要清空所有场景数据吗？', '确认清空', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })

    deployedEquipment.value = []
    savedRoutes.value = []
    currentRoute.value = null
    selectedEquipment.value = null
    isPlanning.value = false

    if (mapViewerRef.value) {
      mapViewerRef.value.clearRoute()
    }

    ElMessage.success('场景已清空')
    showQuickPanel.value = false
  } catch {
    // 用户取消
  }
}

const importScene = () => {
  const input = document.createElement('input')
  input.type = 'file'
  input.accept = '.json'
  input.onchange = (event) => {
    const file = event.target.files[0]
    if (file) {
      const reader = new FileReader()
      reader.onload = (e) => {
        try {
          const sceneData = JSON.parse(e.target.result)
          // 导入场景数据的逻辑
          ElMessage.success('场景导入成功')
        } catch {
          ElMessage.error('文件格式错误')
        }
      }
      reader.readAsText(file)
    }
  }
  input.click()
  showQuickPanel.value = false
}

const exportScene = () => {
  const sceneData = {
    project: currentProject,
    equipment: deployedEquipment.value,
    routes: savedRoutes.value,
    timestamp: new Date().toISOString()
  }

  const dataStr = JSON.stringify(sceneData, null, 2)
  const blob = new Blob([dataStr], { type: 'application/json' })
  const url = URL.createObjectURL(blob)

  const link = document.createElement('a')
  link.href = url
  link.download = `${currentProject.name}_${Date.now()}.json`
  link.click()

  URL.revokeObjectURL(url)
  ElMessage.success('场景已导出')
  showQuickPanel.value = false
}

// 键盘快捷键
const handleKeydown = (event) => {
  if (event.ctrlKey && event.key === 's') {
    event.preventDefault()
    quickSave()
  } else if (event.key === 'Escape') {
    if (isPlanning.value) {
      handleCancelPlanning()
    }
    showQuickPanel.value = false
    showShortcuts.value = false
  } else if (event.key === ' ' && !event.target.matches('input, textarea')) {
    event.preventDefault()
    showQuickPanel.value = !showQuickPanel.value
  } else if (event.key === 'F1') {
    event.preventDefault()
    showShortcuts.value = !showShortcuts.value
  }
}

// 修复错误弹窗按钮可见性
const fixErrorPanelButtons = () => {
  // 查找所有可能的错误面板按钮
  const selectors = [
    '.cesium-widget-errorPanel button',
    '[class*="error"] button',
    '[class*="Error"] button',
    'div[role="dialog"] button',
    'div[role="alert"] button'
  ]
  
  selectors.forEach(selector => {
    const buttons = document.querySelectorAll(selector)
    buttons.forEach(button => {
      if (button) {
        // 强制设置按钮可见
        button.style.cssText = `
          display: inline-block !important;
          visibility: visible !important;
          opacity: 1 !important;
          position: relative !important;
          z-index: 9999 !important;
          margin: 15px auto 10px auto !important;
          background: #263445 !important;
          border: 1px solid #2d3a4b !important;
          color: #bfcbd9 !important;
          padding: 8px 16px !important;
          border-radius: 4px !important;
          cursor: pointer !important;
          min-width: 60px !important;
          text-align: center !important;
          height: auto !important;
          width: auto !important;
          overflow: visible !important;
        `
        
        // 添加悬停效果
        button.addEventListener('mouseenter', () => {
          button.style.background = '#2d3a4b !important'
          button.style.borderColor = '#409EFF !important'
          button.style.color = '#409EFF !important'
        })
        
        button.addEventListener('mouseleave', () => {
          button.style.background = '#263445 !important'
          button.style.borderColor = '#2d3a4b !important'
          button.style.color = '#bfcbd9 !important'
        })
      }
    })
  })
}

// 生命周期钩子
onMounted(() => {
  document.addEventListener('keydown', handleKeydown)

  // 定期检查并修复错误面板按钮
  const buttonFixInterval = setInterval(() => {
    fixErrorPanelButtons()
  }, 1000)

  // 模拟性能监控
  setInterval(() => {
    performanceGood.value = Math.random() > 0.2
  }, 5000)

  // 在组件卸载时清理定时器
  onBeforeUnmount(() => {
    clearInterval(buttonFixInterval)
  })
})

onBeforeUnmount(() => {
  document.removeEventListener('keydown', handleKeydown)
  document.removeEventListener('mousemove', handleResize)
  document.removeEventListener('mouseup', stopResize)
})
</script>

<style scoped>
/* 主容器 - 适配侧边栏布局 */
.scenario-workbench {
  width: 96vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: #1f2d3d; /* 使用与侧边栏一致的深色背景 */
  overflow: hidden;
  position: absolute;
  top: 0;
  left: 4vw;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* 顶部工具栏 */
.workbench-header {
  height: 7vh;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 2vw;
  background: linear-gradient(135deg, #263445, #1f2d3d); /* 使用深色渐变 */
  border-bottom: 1px solid #2d3a4b; /* 深色边框 */
  box-shadow: 0 0.2vh 0.8vh rgba(0, 0, 0, 0.3); /* 加深阴影 */
  z-index: 10;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 2vw;
}

.workbench-title {
  margin: 0;
  font-size: 1.4rem;
  font-weight: 600;
  color: #bfcbd9; /* 使用与侧边栏一致的文字颜色 */
  display: flex;
  align-items: center;
  gap: 1vw;
}

.title-icon {
  font-size: 1.6rem;
  color: var(--el-color-primary);
}

.project-info {
  display: flex;
  align-items: center;
  gap: 0.8vw;
}

.header-actions {
  display: flex;
  gap: 1vw;
}

.action-group .el-button {
  height: 3.5vh;
  font-size: 0.85rem;
}

/* 主工作区域 */
.workbench-content {
  flex: 1;
  display: flex;
  overflow: hidden;
  min-height: 0; /* 重要：确保flex子项可以收缩 */
}

/* 左侧面板 */
.left-panel {
  background: #263445; /* 使用深色背景 */
  border-right: 1px solid #2d3a4b; /* 深色边框 */
  position: relative;
  min-width: 300px;
  max-width: 450px;
  flex-shrink: 0; /* 防止收缩 */
}

/* 右侧面板 */
.right-panel {
  background: #263445; /* 使用深色背景 */
  border-left: 1px solid #2d3a4b; /* 深色边框 */
  position: relative;
  min-width: 350px;
  max-width: 500px;
  flex-shrink: 0; /* 防止收缩 */
}

/* 面板标签页 */
.panel-tabs {
  height: 100%;
}

.panel-tabs :deep(.el-tabs__header) {
  margin: 0;
  background: #1f2d3d; /* 使用深色背景 */
  border-bottom: 1px solid #2d3a4b; /* 深色边框 */
}

.panel-tabs :deep(.el-tabs__content) {
  height: calc(100% - 5vh);
  overflow-y: auto; /* 允许垂直滚动 */
  overflow-x: hidden; /* 隐藏水平滚动 */
}

/* 面板标签页滚动条深色主题样式 */
.panel-tabs :deep(.el-tabs__content)::-webkit-scrollbar {
  width: 8px;
}

.panel-tabs :deep(.el-tabs__content)::-webkit-scrollbar-track {
  background: #1f2d3d;
  border-radius: 4px;
}

.panel-tabs :deep(.el-tabs__content)::-webkit-scrollbar-thumb {
  background: #2d3a4b;
  border-radius: 4px;
  transition: background 0.3s ease;
}

.panel-tabs :deep(.el-tabs__content)::-webkit-scrollbar-thumb:hover {
  background: #409EFF;
}

.panel-tabs :deep(.el-tab-pane) {
  height: 100%;
  background: #263445; /* 统一深色背景 */
}

/* Element Plus 标签页样式覆盖 */
.panel-tabs :deep(.el-tabs__item) {
  color: #bfcbd9 !important; /* 统一文字颜色 */
  background: transparent !important;
}

.panel-tabs :deep(.el-tabs__item.is-active) {
  color: #409EFF !important; /* 激活状态颜色 */
}

.panel-tabs :deep(.el-tabs__item:hover) {
  color: #409EFF !important; /* 悬停状态颜色 */
}

.panel-tabs :deep(.el-tabs__active-bar) {
  background-color: #409EFF !important; /* 激活指示条颜色 */
}

/* 面板调整器 */
.panel-resizer {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 0.4vw;
  background: transparent;
  cursor: col-resize;
  z-index: 5;
  transition: background-color 0.2s ease;
}

.left-resizer {
  right: -0.2vw;
}

.right-resizer {
  left: -0.2vw;
}

.panel-resizer:hover {
  background: #409EFF; /* 使用侧边栏激活色 */
}

/* 中央地图区域 */
.map-area {
  flex: 1;
  padding: 0;
  background: #0a0f1b; /* 使用更深的背景色以区分地图区域 */
  position: relative;
  overflow: hidden;
}

/* 底部状态栏 */
.workbench-footer {
  height: 5vh;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 2vw;
  background: #1f2d3d; /* 使用深色背景 */
  border-top: 1px solid #2d3a4b; /* 深色边框 */
  font-size: 0.8rem;
}

.status-left, .status-right {
  display: flex;
  align-items: center;
  gap: 2vw;
}

.status-item {
  display: flex;
  align-items: center;
  gap: 0.5vw;
  color: #bfcbd9; /* 使用深色主题的文字颜色 */
}

.zoom-controls {
  display: flex;
  align-items: center;
}

.zoom-controls .el-button {
  height: 2.5vh;
  width: 2.5vh;
  padding: 0;
  font-size: 0.7rem;
}

.performance-indicator {
  display: flex;
  align-items: center;
  gap: 0.5vw;
}

.perf-icon {
  font-size: 0.9rem;
  color: var(--el-color-warning);
  transition: color 0.3s ease;
}

.perf-icon.active {
  color: var(--el-color-success);
}

.perf-text {
  font-size: 0.8rem;
  color: #bfcbd9; /* 使用深色主题的文字颜色 */
}

/* 快捷操作浮动面板 */
.quick-panel {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: #263445; /* 使用深色背景 */
  border: 1px solid #2d3a4b; /* 深色边框 */
  border-radius: 1vh;
  padding: 2vh;
  box-shadow: 0 1vh 3vh rgba(0, 0, 0, 0.5); /* 加深阴影 */
  z-index: 2000;
  min-width: 25vw;
}

.quick-title {
  font-size: 1.1rem;
  font-weight: 600;
  color: #bfcbd9; /* 使用深色主题的文字颜色 */
  margin-bottom: 1.5vh;
  text-align: center;
}

.quick-actions {
  display: flex;
  flex-direction: column;
  gap: 1vh;
}

.quick-actions .el-button {
  justify-content: flex-start;
  height: 4vh;
}

/* 快捷键提示 */
.shortcut-tips {
  position: fixed;
  top: 10vh;
  right: 2vw;
  background: #263445; /* 使用深色背景 */
  border: 1px solid #2d3a4b; /* 深色边框 */
  border-radius: 0.8vh;
  padding: 1.5vh;
  box-shadow: 0 0.5vh 2vh rgba(0, 0, 0, 0.3); /* 加深阴影 */
  z-index: 1000;
  min-width: 15vw;
}

.tips-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1vh;
  font-weight: 600;
  color: #bfcbd9; /* 使用深色主题的文字颜色 */
}

.tips-content {
  display: flex;
  flex-direction: column;
  gap: 0.8vh;
}

.tip-item {
  font-size: 0.8rem;
  color: #bfcbd9; /* 使用深色主题的文字颜色 */
  display: flex;
  align-items: center;
  gap: 0.5vw;
}

kbd {
  background: #1f2d3d; /* 使用深色背景 */
  border: 1px solid #2d3a4b; /* 深色边框 */
  border-radius: 0.3vh;
  padding: 0.2vh 0.5vw;
  font-size: 0.7rem;
  font-family: 'Monaco', 'Consolas', monospace;
  color: #bfcbd9; /* 使用深色主题的文字颜色 */
}

/* 过渡动画 */
.fade-enter-active, .fade-leave-active {
  transition: all 0.3s ease;
}

.fade-enter-from, .fade-leave-to {
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.9);
}

/* 响应式设计 */
@media (max-width: 1400px) {
  .left-panel {
    min-width: 260px;
    max-width: 350px;
  }
  
  .right-panel {
    min-width: 300px;
    max-width: 400px;
  }
}

@media (max-width: 1200px) {
  .workbench-title {
    font-size: 1.2rem;
  }

  .project-info {
    display: none;
  }

  .status-left .status-item:nth-child(n+3) {
    display: none;
  }
  
  .left-panel {
    min-width: 240px;
    max-width: 320px;
  }
  
  .right-panel {
    min-width: 280px;
    max-width: 360px;
  }
}

@media (max-width: 768px) {
  .scenario-workbench {
    width: 100vw;
    left: 0;
  }
  
  .workbench-header {
    height: 8vh;
    padding: 0 1vw;
  }

  .left-panel, .right-panel {
    min-width: 180px;
    max-width: 220px;
  }

  .quick-panel {
    min-width: 80vw;
  }

  .shortcut-tips {
    right: 1vw;
    min-width: 40vw;
  }
}

/* 滚动条样式 */
:deep(.el-scrollbar__bar) {
  opacity: 0.3;
}

:deep(.el-scrollbar__bar:hover) {
  opacity: 0.6;
}

/* Element Plus 组件深色主题全局覆盖 */
.scenario-workbench :deep(.el-button) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
}

.scenario-workbench :deep(.el-button:hover) {
  background: #2d3a4b !important;
  border-color: #409EFF !important;
  color: #409EFF !important;
}

.scenario-workbench :deep(.el-button--primary) {
  background: #409EFF !important;
  border-color: #409EFF !important;
  color: #ffffff !important;
}

.scenario-workbench :deep(.el-button--primary:hover) {
  background: #66B2FF !important;
  border-color: #66B2FF !important;
}

.scenario-workbench :deep(.el-tag) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
}

.scenario-workbench :deep(.el-tag--success) {
  background: #1f4838 !important;
  border-color: #2d5a41 !important;
  color: #67C23A !important;
}

.scenario-workbench :deep(.el-tag--info) {
  background: #1f2d3d !important;
  border-color: #2d3a4b !important;
  color: #909399 !important;
}

.scenario-workbench :deep(.el-button-group .el-button) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
}

.scenario-workbench :deep(.el-button-group .el-button:hover) {
  background: #2d3a4b !important;
  border-color: #409EFF !important;
  color: #409EFF !important;
}

/* 确保所有文本颜色统一 */
.scenario-workbench :deep(*) {
  color: #bfcbd9;
}

.scenario-workbench :deep(.el-icon) {
  color: #bfcbd9 !important;
}

/* 更全面的 Element Plus 组件深色主题覆盖 */
.scenario-workbench :deep(.el-input) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
}

.scenario-workbench :deep(.el-input__wrapper) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  box-shadow: 0 0 0 1px #2d3a4b inset !important;
}

.scenario-workbench :deep(.el-input__inner) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
}

.scenario-workbench :deep(.el-textarea) {
  background: #263445 !important;
}

.scenario-workbench :deep(.el-textarea__inner) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
  box-shadow: none !important;
}

.scenario-workbench :deep(.el-textarea__inner:focus) {
  border-color: #409EFF !important;
  box-shadow: 0 0 0 1px #409EFF !important;
}

.scenario-workbench :deep(.el-select) {
  background: #263445 !important;
}

.scenario-workbench :deep(.el-select .el-input__wrapper) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  box-shadow: 0 0 0 1px #2d3a4b inset !important;
}

.scenario-workbench :deep(.el-select .el-input__inner) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
}

/* 更强的选择器样式覆盖 */
.scenario-workbench :deep(.el-select__wrapper) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  box-shadow: 0 0 0 1px #2d3a4b inset !important;
}

.scenario-workbench :deep(.el-select:hover .el-input__wrapper) {
  box-shadow: 0 0 0 1px #2d3a4b inset !important;
}

.scenario-workbench :deep(.el-select.is-focused .el-input__wrapper) {
  box-shadow: 0 0 0 1px #409EFF inset !important;
}

.scenario-workbench :deep(.el-select__suffix) {
  color: #8591a3 !important;
}

.scenario-workbench :deep(.el-select__caret) {
  color: #8591a3 !important;
}

.scenario-workbench :deep(.el-select__caret:hover) {
  color: #409EFF !important;
}

.scenario-workbench :deep(.el-date-editor) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
}

.scenario-workbench :deep(.el-date-editor .el-input__wrapper) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  box-shadow: 0 0 0 1px #2d3a4b inset !important;
}

.scenario-workbench :deep(.el-date-editor .el-input__inner) {
  background: #263445 !important;
  color: #bfcbd9 !important;
}

.scenario-workbench :deep(.el-input-number) {
  background: #263445 !important;
}

.scenario-workbench :deep(.el-input-number .el-input__wrapper) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  box-shadow: 0 0 0 1px #2d3a4b inset !important;
}

.scenario-workbench :deep(.el-input-number .el-input__inner) {
  background: #263445 !important;
  color: #bfcbd9 !important;
}

.scenario-workbench :deep(.el-dropdown) {
  background: #263445 !important;
  color: #bfcbd9 !important;
}

/* 下拉菜单选项 */
.scenario-workbench :deep(.el-select-dropdown) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
}

.scenario-workbench :deep(.el-select-dropdown__item) {
  background: #263445 !important;
  color: #bfcbd9 !important;
}

.scenario-workbench :deep(.el-select-dropdown__item:hover) {
  background: #2d3a4b !important;
  color: #409EFF !important;
}

.scenario-workbench :deep(.el-select-dropdown__item.selected) {
  background: #409EFF !important;
  color: #ffffff !important;
}

/* 日期选择器弹窗 */
.scenario-workbench :deep(.el-picker-panel) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
}

.scenario-workbench :deep(.el-date-picker__header) {
  background: #1f2d3d !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
}

.scenario-workbench :deep(.el-picker-panel__content) {
  background: #263445 !important;
}

.scenario-workbench :deep(.el-date-table td) {
  color: #bfcbd9 !important;
}

.scenario-workbench :deep(.el-date-table td.available:hover) {
  background: #2d3a4b !important;
  color: #409EFF !important;
}

.scenario-workbench :deep(.el-date-table td.current) {
  background: #409EFF !important;
  color: #ffffff !important;
}

.scenario-workbench :deep(.el-card) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
}

.scenario-workbench :deep(.el-card__header) {
  background: #1f2d3d !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
}

.scenario-workbench :deep(.el-card__body) {
  background: #263445 !important;
  color: #bfcbd9 !important;
}

.scenario-workbench :deep(.el-form-item__label) {
  color: #bfcbd9 !important;
}

/* 滑块组件 */
.scenario-workbench :deep(.el-slider) {
  background: transparent !important;
}

.scenario-workbench :deep(.el-slider__runway) {
  background: #2d3a4b !important;
}

.scenario-workbench :deep(.el-slider__bar) {
  background: #409EFF !important;
}

.scenario-workbench :deep(.el-slider__button) {
  background: #409EFF !important;
  border-color: #409EFF !important;
}

/* 评分组件 */
.scenario-workbench :deep(.el-rate) {
  color: #2d3a4b !important;
}

.scenario-workbench :deep(.el-rate__item.is-active) {
  color: #409EFF !important;
}

.scenario-workbench :deep(.el-rate__text) {
  color: #bfcbd9 !important;
}

/* 输入框聚焦状态 */
.scenario-workbench :deep(.el-input__wrapper:focus),
.scenario-workbench :deep(.el-input__wrapper.is-focus) {
  box-shadow: 0 0 0 1px #409EFF inset !important;
}

/* 已在上面合并 */

/* placeholder文字颜色 */
.scenario-workbench :deep(.el-input__inner::placeholder),
.scenario-workbench :deep(.el-textarea__inner::placeholder) {
  color: #8591a3 !important;
}

/* 输入框计数器样式 */
.scenario-workbench :deep(.el-input__count) {
  background: #263445 !important;
  color: #8591a3 !important;
}

/* 输入框后缀图标 */
.scenario-workbench :deep(.el-input__suffix) {
  color: #8591a3 !important;
}

.scenario-workbench :deep(.el-input__suffix-inner) {
  color: #8591a3 !important;
}

/* 选择器箭头图标 */
.scenario-workbench :deep(.el-select__caret) {
  color: #8591a3 !important;
}

/* 数字输入框控制按钮 */
.scenario-workbench :deep(.el-input-number__decrease),
.scenario-workbench :deep(.el-input-number__increase) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  color: #8591a3 !important;
}

.scenario-workbench :deep(.el-input-number__decrease:hover),
.scenario-workbench :deep(.el-input-number__increase:hover) {
  background: #2d3a4b !important;
  color: #409EFF !important;
}

.scenario-workbench :deep(.el-checkbox__label) {
  color: #bfcbd9 !important;
}

.scenario-workbench :deep(.el-radio__label) {
  color: #bfcbd9 !important;
}

.scenario-workbench :deep(.el-table) {
  background: #263445 !important;
  color: #bfcbd9 !important;
}

.scenario-workbench :deep(.el-table th) {
  background: #1f2d3d !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
}

.scenario-workbench :deep(.el-table td) {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
}

/* 子组件内的文本确保统一 */
.scenario-workbench :deep(span),
.scenario-workbench :deep(div),
.scenario-workbench :deep(p),
.scenario-workbench :deep(h1),
.scenario-workbench :deep(h2),
.scenario-workbench :deep(h3),
.scenario-workbench :deep(h4),
.scenario-workbench :deep(h5),
.scenario-workbench :deep(h6) {
  color: #bfcbd9 !important;
}

/* 深色模式适配 - 已默认应用深色主题 */
@media (prefers-color-scheme: dark) {
  .workbench-header {
    background: linear-gradient(135deg, #263445, #1f2d3d);
  }

  .panel-resizer:hover {
    background: #409EFF;
  }
}
</style>

<!-- 全局样式覆盖，用于处理挂载到body的Element Plus组件 -->
<style>
/* 全局 Element Plus 弹出层深色主题覆盖 */
.el-select-dropdown {
  background: #263445 !important;
  border-color: #2d3a4b !important;
}

/* 全局按钮显示修复 - 确保所有错误弹窗按钮都可见 */
button,
input[type="button"],
input[type="submit"] {
  display: inline-block !important;
  visibility: visible !important;
  opacity: 1 !important;
  position: relative !important;
}

/* 特别针对Cesium和其他地图库的错误处理 */
.cesium-widget-errorPanel button,
.cesium-button,
[class*="cesium"] button,
[class*="error"] button,
[class*="Error"] button,
div[role="dialog"] button,
div[role="alert"] button {
  display: inline-block !important;
  visibility: visible !important;
  opacity: 1 !important;
  position: relative !important;
  z-index: 9999 !important;
  margin: 10px auto !important;
  background: #263445 !important;
  border: 1px solid #2d3a4b !important;
  color: #bfcbd9 !important;
  padding: 8px 16px !important;
  border-radius: 4px !important;
  cursor: pointer !important;
  min-width: 60px !important;
  text-align: center !important;
}

/* 悬停状态 */
.cesium-widget-errorPanel button:hover,
.cesium-button:hover,
[class*="cesium"] button:hover,
[class*="error"] button:hover,
[class*="Error"] button:hover,
div[role="dialog"] button:hover,
div[role="alert"] button:hover {
  background: #2d3a4b !important;
  border-color: #409EFF !important;
  color: #409EFF !important;
}

/* 最强制性的按钮显示规则 */
body .cesium-widget-errorPanel button,
body [class*="error"] button,
body [class*="Error"] button {
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
  height: auto !important;
  width: auto !important;
  overflow: visible !important;
  position: static !important;
  margin: 15px auto 10px auto !important;
}

.el-select-dropdown__item {
  background: #263445 !important;
  color: #bfcbd9 !important;
}

.el-select-dropdown__item:hover {
  background: #2d3a4b !important;
  color: #409EFF !important;
}

.el-select-dropdown__item.selected {
  background: #409EFF !important;
  color: #ffffff !important;
}

.el-picker-panel {
  background: #263445 !important;
  border-color: #2d3a4b !important;
}

.el-date-picker__header {
  background: #1f2d3d !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
}

.el-picker-panel__content {
  background: #263445 !important;
}

.el-date-table td {
  color: #bfcbd9 !important;
}

.el-date-table td.available:hover {
  background: #2d3a4b !important;
  color: #409EFF !important;
}

.el-date-table td.current {
  background: #409EFF !important;
  color: #ffffff !important;
}

.el-date-table th {
  color: #bfcbd9 !important;
}

.el-picker__popper {
  background: #263445 !important;
  border-color: #2d3a4b !important;
}

.el-time-panel {
  background: #263445 !important;
  border-color: #2d3a4b !important;
}

.el-time-panel__content {
  background: #263445 !important;
}

.el-scrollbar__thumb {
  background: #2d3a4b !important;
}

.el-scrollbar__bar {
  background: transparent !important;
}

.el-popper {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
}

.el-tooltip__popper {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
}

.el-picker-panel__footer {
  background: #1f2d3d !important;
  border-color: #2d3a4b !important;
}

.el-picker-panel__sidebar {
  background: #1f2d3d !important;
  border-color: #2d3a4b !important;
}

.el-picker-panel__sidebar li {
  color: #bfcbd9 !important;
}

.el-picker-panel__sidebar li:hover {
  background: #2d3a4b !important;
  color: #409EFF !important;
}

.el-picker-panel__sidebar li.selected {
  background: #409EFF !important;
  color: #ffffff !important;
}

/* 输入框悬停状态 */
.el-input__wrapper:hover {
  box-shadow: 0 0 0 1px #2d3a4b inset !important;
}

/* 文本域字数统计 */
.el-textarea .el-input__count {
  background: #263445 !important;
  color: #8591a3 !important;
}

/* 选择器清除按钮 */
.el-select__suffix .el-select__clear {
  color: #8591a3 !important;
}

.el-select__suffix .el-select__clear:hover {
  color: #409EFF !important;
}

/* 日期选择器清除按钮 */
.el-input__suffix .el-icon {
  color: #8591a3 !important;
}

.el-input__suffix .el-icon:hover {
  color: #409EFF !important;
}

/* 额外的选择器强制覆盖 */
.el-select {
  background: #263445 !important;
}

.el-select .el-input__wrapper {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  box-shadow: 0 0 0 1px #2d3a4b inset !important;
}

.el-select .el-input__inner {
  background: #263445 !important;
  color: #bfcbd9 !important;
}

.el-select__wrapper {
  background: #263445 !important;
  border-color: #2d3a4b !important;
}

.el-select:hover .el-input__wrapper {
  box-shadow: 0 0 0 1px #2d3a4b inset !important;
}

.el-select.is-focused .el-input__wrapper {
  box-shadow: 0 0 0 1px #409EFF inset !important;
}

/* 全局文本域样式强制覆盖 */
.el-textarea {
  background: #263445 !important;
}

.el-textarea__inner {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
  box-shadow: none !important;
}

.el-textarea__inner:focus {
  border-color: #409EFF !important;
  box-shadow: 0 0 0 1px #409EFF !important;
}

.el-textarea__inner::placeholder {
  color: #8591a3 !important;
}

/* 强制显示所有错误弹窗中的按钮 */
.cesium-widget-errorPanel *,
div[class*="error"] *,
div[class*="Error"] * {
  max-height: none !important;
  overflow: visible !important;
}

/* 确保Cesium错误面板不会隐藏按钮 */
.cesium-widget-errorPanel {
  max-height: none !important;
  height: auto !important;
  overflow: visible !important;
}

/* 处理可能的地图库弹窗按钮样式 */
.cesium-button,
.ol-control button,
button[type="button"] {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
  border-radius: 4px !important;
  padding: 6px 12px !important;
}

.cesium-button:hover,
.ol-control button:hover,
button[type="button"]:hover {
  background: #2d3a4b !important;
  border-color: #409EFF !important;
  color: #409EFF !important;
}

/* 针对可能的错误弹窗 */
.cesium-widget-errorPanel {
  background: rgba(31, 45, 61, 0.95) !important;
  color: #bfcbd9 !important;
  padding: 20px !important;
  border-radius: 6px !important;
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: space-between !important;
  min-height: 150px !important;
}

.cesium-widget-errorPanel button {
  background: #263445 !important;
  border: 1px solid #2d3a4b !important;
  color: #bfcbd9 !important;
  margin-top: 20px !important; /* 合理的按钮距离 */
  padding: 8px 16px !important;
  border-radius: 4px !important;
  cursor: pointer !important;
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
  position: static !important;
}

div[class*="error"] button,
div[class*="Error"] button {
  background: #263445 !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
  margin-top: 15px !important; /* 合理的按钮距离 */
}

.cesium-widget-errorPanel button:hover,
div[class*="error"] button:hover,
div[class*="Error"] button:hover {
  background: #2d3a4b !important;
  border-color: #409EFF !important;
  color: #409EFF !important;
}

/* 更通用的错误弹窗按钮间距处理 */
div[role="alert"] button,
.error-dialog button,
.error-modal button,
[class*="error-panel"] button,
[class*="Error-panel"] button {
  margin-top: 15px !important; /* 合理的按钮距离 */
  background: #263445 !important;
  border-color: #2d3a4b !important;
  color: #bfcbd9 !important;
  padding: 8px 16px !important;
  border-radius: 4px !important;
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
}

div[role="alert"] button:hover,
.error-dialog button:hover,
.error-modal button:hover,
[class*="error-panel"] button:hover,
[class*="Error-panel"] button:hover {
  background: #2d3a4b !important;
  border-color: #409EFF !important;
  color: #409EFF !important;
}
</style>
